

package com.walk.zworld.ui.activity

import android.app.Activity
import android.content.Intent
import android.content.res.Configuration
import android.os.Parcelable
import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import com.shuyu.gsyvideoplayer.GSYVideoADManager
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import com.walk.zworld.BR
import com.walk.zworld.R
import com.walk.zworld.databinding.ActivityNewDetailBinding
import com.walk.zworld.square.*
import com.walk.zworld.square.model.Author
import com.walk.zworld.square.model.Consumption
import com.walk.zworld.square.model.Cover
import com.walk.zworld.square.model.WebUrl
import com.walk.zworld.square.network.ResponseHandler
import com.walk.zworld.square.newdetail.NewDetailRelatedAdapter
import com.walk.zworld.square.newdetail.NewDetailReplyAdapter
import com.walk.zworld.square.newdetail.NewDetailViewModel
import com.base.lib.base.view.BaseMvvmDataBindingActivity
import com.base.lib.base.widget.MyRefreshFooter
import com.base.lib.module.setOnClickListener
import com.base.lib.net.utils.ext.view.showToast
import com.walk.zworld.square.gone
import com.walk.zworld.square.goneAlphaAnimation
import com.walk.zworld.square.invisibleAlphaAnimation
import com.walk.zworld.square.load
import com.walk.zworld.square.visible
import com.walk.zworld.square.visibleAlphaAnimation
import kotlinx.android.parcel.Parcelize
import kotlinx.coroutines.*


/**
 * 视频详情界面。
 * @since  2020/5/14
 */
class NewDetailActivity : BaseMvvmDataBindingActivity<ActivityNewDetailBinding, NewDetailViewModel>() {

    private lateinit var relatedAdapter: NewDetailRelatedAdapter

    private lateinit var replyAdapter: NewDetailReplyAdapter

    private lateinit var mergeAdapter: ConcatAdapter

    private var orientationUtils: OrientationUtils? = null

    private val globalJob by lazy { Job() }

    private var hideTitleBarJob: Job? = null

    private var hideBottomContainerJob: Job? = null


    override fun onBindVariableId(): MutableList<Pair<Int, Any>> {
        return arrayListOf(BR.viewModel to mViewModel)
    }

    override fun onBindViewModel(): Class<NewDetailViewModel> = NewDetailViewModel::class.java

    override fun onBindLayout(): Int  = R.layout.activity_new_detail

    override fun initView() {
        setupViews()
    }

    override fun initData() {
    }

    override fun setContentView(layoutView: View) {
        if (checkArguments()) {
            super.setContentView(layoutView)
            setStatusBarBackground(R.color.black)
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        if (checkArguments()) {
            initParams()
            startVideoPlayer()
            mViewModel.onRefresh()
        }
    }

    override fun onPause() {
        super.onPause()
        binding?.videoPlayer?.onVideoPause()
    }

    override fun onResume() {
        super.onResume()
        binding?.videoPlayer?.onVideoResume()
    }

    override fun onDestroy() {
        super.onDestroy()
        GSYVideoADManager.releaseAllVideos()
        orientationUtils?.releaseListener()
        binding?.videoPlayer?.release()
        binding?.videoPlayer?.setVideoAllCallBack(null)
        binding?.videoPlayer?.onDestroy();
        globalJob.cancel()
    }

    override fun onBackPressed() {
        orientationUtils?.backToProtVideo()
        if (GSYVideoManager.backFromWindowFull(this)) return
        super.onBackPressed()
    }

    override fun finish() {
        super.finish()
        overridePendingTransition(0, R.anim.anl_push_bottom_out)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        binding?.videoPlayer?.onConfigurationChanged(this, newConfig, orientationUtils, true, true)
    }

    fun setupViews() {
        initParams()
        val binding1 = binding!!
        orientationUtils = OrientationUtils(this, binding1.videoPlayer)
        relatedAdapter = NewDetailRelatedAdapter(this, mViewModel.relatedDataList, mViewModel.videoInfoData)
        replyAdapter = NewDetailReplyAdapter(this, mViewModel.repliesDataList)
        mergeAdapter = ConcatAdapter(relatedAdapter, replyAdapter)
        binding1.recyclerView.layoutManager = LinearLayoutManager(this)
        binding1.recyclerView.adapter = mergeAdapter
        binding1.recyclerView.setHasFixedSize(true)
        binding1.recyclerView.itemAnimator = null
        binding1.refreshLayout.run {
            setDragRate(0.7f)
            setHeaderTriggerRate(0.6f)
            setFooterTriggerRate(0.6f)
            setEnableLoadMoreWhenContentNotFull(true)
            setEnableFooterFollowWhenNoMoreData(true)
            setEnableFooterTranslationContent(true)
            setEnableScrollContentWhenLoaded(true)
            binding1.refreshLayout.setEnableNestedScroll(true)
            setFooterHeight(153f)
            setRefreshFooter(MyRefreshFooter(this@NewDetailActivity).apply {
                setAccentColorId(R.color.white)
                setBackgroundColor(ContextCompat.getColor(context, R.color.transparent))
                setPrimaryColor(ContextCompat.getColor(context, R.color.transparent))
            })
            setOnRefreshListener { finish() }
            setOnLoadMoreListener { mViewModel.onLoadMore() }
        }
        setOnClickListener(
            binding1.ivPullDown, binding1.ivMore, binding1.ivShare, binding1.ivCollection, binding1.ivToWechatFriends, binding1.ivShareToWechatMemories,
            binding1.ivShareToWeibo, binding1.ivShareToQQ, binding1.ivShareToQQzone, binding1.ivAvatar, binding1.etComment, binding1.ivReply, binding1.tvReplyCount,
            listener = ClickListener()
        )
        observe()
        startVideoPlayer()
        mViewModel.onRefresh()
    }

    private fun checkArguments() = if (intent.getParcelableExtra<VideoInfo>(EXTRA_VIDEOINFO) == null && intent.getLongExtra(
            EXTRA_VIDEO_ID, 0L) == 0L) {
        "跳转界面出现未知异常".showToast()
        finish()
        false
    } else {
        true
    }

    private fun startVideoPlayer() {
        mViewModel.videoInfoData?.run {
            binding?.ivBlurredBg?.load(cover.blurred)
            binding?.tvReplyCount?.text = consumption.replyCount.toString()
            binding?.videoPlayer?.startPlay()
        }
    }

    private fun initParams() {
        if (intent.getParcelableExtra<VideoInfo>(EXTRA_VIDEOINFO) != null) mViewModel.videoInfoData = intent.getParcelableExtra(
            EXTRA_VIDEOINFO
        )
        if (intent.getLongExtra(EXTRA_VIDEO_ID, 0L) != 0L) mViewModel.videoId = intent.getLongExtra(
            EXTRA_VIDEO_ID, 0L)
    }

    private fun observe() {
        //刷新，视频信息+相关推荐+评论
        if (!mViewModel.videoDetailLiveData.hasObservers()) {
            mViewModel.videoDetailLiveData.observe(this, Observer { result ->
                val response = result.getOrNull()
                if (response == null) {
                    ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()
                    return@Observer
                }
                mViewModel.nextPageUrl = response.videoReplies.nextPageUrl
                if (response.videoRelated == null || response.videoRelated.itemList.isNullOrEmpty() && response.videoReplies.itemList.isNullOrEmpty()) {
                    return@Observer
                }
                response.videoBeanForClient?.run {
                    mViewModel.videoInfoData = VideoInfo(id, playUrl, title, description, category, library, consumption, cover, author, webUrl)
                    startVideoPlayer()
                    relatedAdapter.bindVideoInfo(mViewModel.videoInfoData)
                }
                mViewModel.relatedDataList.clear()
                mViewModel.repliesDataList.clear()
                mViewModel.relatedDataList.addAll(response.videoRelated.itemList)
                mViewModel.repliesDataList.addAll(response.videoReplies.itemList)
                relatedAdapter.notifyDataSetChanged()
                replyAdapter.notifyDataSetChanged()
                when {
                    mViewModel.repliesDataList.isNullOrEmpty() -> binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                    response.videoReplies.nextPageUrl.isNullOrEmpty() -> binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                    else -> binding?.refreshLayout?.closeHeaderOrFooter()
                }
            })
        }
        //刷新，相关推荐+评论
        if (!mViewModel.repliesAndRepliesLiveData.hasObservers()) {
            mViewModel.repliesAndRepliesLiveData.observe(this, Observer { result ->
                val response = result.getOrNull()
                if (response == null) {
                    ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()
                    return@Observer
                }
                mViewModel.nextPageUrl = response.videoReplies.nextPageUrl
                if (response.videoRelated == null || response.videoRelated.itemList.isNullOrEmpty() && response.videoReplies.itemList.isNullOrEmpty()) {
                    return@Observer
                }
                mViewModel.relatedDataList.clear()
                mViewModel.repliesDataList.clear()
                mViewModel.relatedDataList.addAll(response.videoRelated.itemList)
                mViewModel.repliesDataList.addAll(response.videoReplies.itemList)
                relatedAdapter.bindVideoInfo(mViewModel.videoInfoData)
                relatedAdapter.notifyDataSetChanged()
                replyAdapter.notifyDataSetChanged()
                when {
                    mViewModel.repliesDataList.isNullOrEmpty() -> binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                    response.videoReplies.nextPageUrl.isNullOrEmpty() -> binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                    else -> binding?.refreshLayout?.closeHeaderOrFooter()
                }
            })
        }
        //上拉加载，评论
        if (!mViewModel.repliesLiveData.hasObservers()) {
            mViewModel.repliesLiveData.observe(this, Observer { result ->
                val response = result.getOrNull()
                if (response == null) {
                    ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()
                    return@Observer
                }
                mViewModel.nextPageUrl = response.nextPageUrl
                if (response.itemList.isNullOrEmpty()) {
                    return@Observer
                }
                val itemCount = replyAdapter.itemCount
                mViewModel.repliesDataList.addAll(response.itemList)
                replyAdapter.notifyItemRangeInserted(itemCount, response.itemList.size)
                if (response.nextPageUrl.isNullOrEmpty()) {
                    binding?.refreshLayout?.finishLoadMoreWithNoMoreData()
                } else {
                    binding?.refreshLayout?.closeHeaderOrFooter()
                }
            })
        }
    }

    private fun GSYVideoPlayer.startPlay() {
        mViewModel.videoInfoData?.let {
            //设置全屏按键功能,这是使用的是选择屏幕，而不是全屏
            fullscreenButton.setOnClickListener { showFull() }
            //防止错位设置
            playTag = TAG
            //音频焦点冲突时是否释放
            isReleaseWhenLossAudio = false
            //增加封面
            val imageView = ImageView(this@NewDetailActivity)
            imageView.scaleType = ImageView.ScaleType.CENTER_CROP
            imageView.load(it.cover.detail)
            thumbImageView = imageView
            thumbImageView.setOnClickListener { switchTitleBarVisible() }
            //是否开启自动旋转
            isRotateViewAuto = false
            //是否需要全屏锁定屏幕功能
            isNeedLockFull = true
            //是否可以滑动调整
            setIsTouchWiget(true)
            //设置触摸显示控制ui的消失时间
            dismissControlTime = 5000
            //设置播放过程中的回调
            setVideoAllCallBack(VideoCallPlayBack())
            //设置播放URL
            setUp(it.playUrl, false, it.title)
            //开始播放
            startPlayLogic()
        }
    }

    private fun switchTitleBarVisible() {
        if (binding?.videoPlayer?.currentPlayer?.currentState == GSYVideoView.CURRENT_STATE_AUTO_COMPLETE) return
        if (binding?.flHeader?.visibility == View.VISIBLE) {
            hideTitleBar()
        } else {
            binding?.flHeader?.visibleAlphaAnimation(1000)
            binding?.ivPullDown?.visibleAlphaAnimation(1000)
            binding?.ivCollection?.visibleAlphaAnimation(1000)
            binding?.ivMore?.visibleAlphaAnimation(1000)
            binding?.ivShare?.visibleAlphaAnimation(1000)
            delayHideTitleBar()
        }
    }

    private fun hideTitleBar() {
        binding?.flHeader?.invisibleAlphaAnimation(1000)
        binding?.ivPullDown?.goneAlphaAnimation(1000)
        binding?.ivCollection?.goneAlphaAnimation(1000)
        binding?.ivMore?.goneAlphaAnimation(1000)
        binding?.ivShare?.goneAlphaAnimation(1000)
    }

    private fun delayHideTitleBar() {
        hideTitleBarJob?.cancel()
        hideTitleBarJob = CoroutineScope(globalJob).launch(Dispatchers.Main) {
            binding?.videoPlayer?.dismissControlTime?.toLong()?.let { delay(it) }
            hideTitleBar()
        }
    }

    private fun delayHideBottomContainer() {
        hideBottomContainerJob?.cancel()
        hideBottomContainerJob = CoroutineScope(globalJob).launch(Dispatchers.Main) {
            binding?.videoPlayer?.dismissControlTime?.let { delay(it.toLong()) }
            binding?.videoPlayer?.getBottomContainer().gone()
            binding?.videoPlayer?.startButton.gone()
        }
    }

    private fun showFull() {
        orientationUtils?.resolveByClick()
    }

    fun scrollTop() {
        if (relatedAdapter.itemCount != 0) {
            binding?.recyclerView?.scrollToPosition(0)
            binding?.refreshLayout?.invisibleAlphaAnimation(2500)
            binding?.refreshLayout?.visibleAlphaAnimation(1500)
        }
    }

    private fun scrollRepliesTop() {
        val targetPostion = (relatedAdapter.itemCount - 1) + 2  //+相关推荐最后一项，+1评论标题，+1条评论
        if (targetPostion < mergeAdapter.itemCount - 1) {
            binding?.recyclerView?.smoothScrollToPosition(targetPostion)
        }
    }

    inner class VideoCallPlayBack : GSYSampleCallBack() {
        override fun onStartPrepared(url: String?, vararg objects: Any?) {
            super.onStartPrepared(url, *objects)
            binding?.flHeader?.gone()
            binding?.llShares?.gone()
        }

        override fun onClickBlank(url: String?, vararg objects: Any?) {
            super.onClickBlank(url, *objects)
            switchTitleBarVisible()
        }

        override fun onClickStop(url: String?, vararg objects: Any?) {
            super.onClickStop(url, *objects)
            delayHideBottomContainer()
        }

        override fun onAutoComplete(url: String?, vararg objects: Any?) {
            super.onAutoComplete(url, *objects)
            binding?.flHeader?.visible()
            binding?.ivPullDown?.visible()
            binding?.ivCollection?.gone()
            binding?.ivShare?.gone()
            binding?.ivMore?.gone()
            binding?.llShares?.visible()
        }
    }

    inner class ClickListener : View.OnClickListener {
        override fun onClick(v: View) {
            mViewModel.videoInfoData?.let {
                when (v) {
                    binding?.ivPullDown -> finish()
//                    binding.ivMore -> {
//                    }
//                    binding.ivShare -> showDialogShare(it.webUrl.raw)
//                    binding.ivCollection -> LoginActivity.start(this@NewDetailActivity)
//                    binding.ivToWechatFriends -> share(it.webUrl.raw, SHARE_WECHAT)
//                    binding.ivShareToWechatMemories -> share(it.webUrl.raw, SHARE_WECHAT_MEMORIES)
//                    binding.ivShareToWeibo -> share(it.webUrl.forWeibo, SHARE_WEIBO)
//                    binding.ivShareToQQ -> share(it.webUrl.raw, SHARE_QQ)
//                    binding.ivShareToQQzone -> share(it.webUrl.raw, SHARE_QQZONE)
//                    binding.ivAvatar, binding.etComment -> LoginActivity.start(this@NewDetailActivity)
//                    binding.ivReply, binding.tvReplyCount -> scrollRepliesTop()
//                    else -> {
//                    }
                }
            }
        }
    }

    @Parcelize
    data class VideoInfo(
        val videoId: Long, val playUrl: String, val title: String, val description: String, val category: String, val library: String,
        val consumption: Consumption, val cover: Cover, val author: Author?, val webUrl: WebUrl
    ) : Parcelable

    companion object {
        const val TAG = "NewDetailActivity"

        const val EXTRA_VIDEOINFO = "videoInfo"
        const val EXTRA_VIDEO_ID = "videoId"

        fun start(context: Activity, videoInfo: VideoInfo) {
            val starter = Intent(context, NewDetailActivity::class.java)
            starter.putExtra(EXTRA_VIDEOINFO, videoInfo)
            context.startActivity(starter)
            context.overridePendingTransition(R.anim.anl_push_bottom_in, R.anim.anl_push_up_out)
        }

        fun start(context: Activity, videoId: Long) {
            val starter = Intent(context, NewDetailActivity::class.java)
            starter.putExtra(EXTRA_VIDEO_ID, videoId)
            context.startActivity(starter)
            context.overridePendingTransition(R.anim.anl_push_bottom_in, R.anim.anl_push_up_out)
        }
    }
}